﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace new_problem
{
    internal class MinimalError
    {
        public static Double[,] CalcMinError(double[,] g, double[] x, double[] y, DataBuffer current)
        {
            double eps = 0.01; // рекомендуемая точность
            double alpha = 0.001; // регуляризующий коэффициент
            Double[,] z0 = DataGen.StartApproximation(); // начальное приближение
            Double[,] A = DataGen.GetFieldGridBySurf(x, y, z0);
            Double[,] dA = DataGen.GetFieldDerivative(x, y, z0);
            Double[,] zk = new double[DataGen.N + 1,DataGen.N + 1]; // for result

            double nrm = MiscUtils.Norm(g); // ||g||
            double err = 1.0;
            int k = 0;
            while (err > eps && k < 20000)
            {
                Double[,] S = MiscUtils.CalcS(A, dA, g);
                double num = MiscUtils.CalcNumerator(A, g);
                double denom = Math.Pow(MiscUtils.Norm(S), 2);
                double coef = alpha*(num/denom);
                double stabFunc = 1.0; // DataGen.StabilisingFunctional(z0);
                for (int i = 0; i <= DataGen.N; i++)
                    for (int j = 0; j <= DataGen.N; j++)
                        zk[i, j] = z0[i, j] + coef * S[i, j] * stabFunc;

                z0 = zk;
                A = DataGen.GetFieldGridBySurf(x, y, z0);
                dA = DataGen.GetFieldDerivative(x, y, z0);
                err = MiscUtils.Norm(MiscUtils.SubstractMatrix(A, g))/nrm;

                alpha = 0.5;

                Console.WriteLine(k + ": " + err + ", alpha: " + alpha);
                k++;
            }
            current.Me = k;
            current.MeErr = err;
            return MiscUtils.SubstractMatrix(new double[DataGen.N + 1, DataGen.N + 1], zk);
        }
    }
}
